package com.ofek.applicationbase.broadcast;

import java.lang.reflect.Method;
import java.util.ArrayList;

import com.ofek.applicationbase.utils.ReflectionUtils;



public class Broadcaster<ListenerType> {
	protected final ArrayList<ListenerType> listeners = new ArrayList<ListenerType>();
	public boolean register(final ListenerType listener) {
		if (listeners.contains(listener)) return false;
		return listeners.add(listener);
	}
	public boolean unregister(final ListenerType listener) {
		return listeners.remove(listener);
	}
	/**
	 * you are being fed with all the listeners, invoke the method needs to be invoked in order to broadcast the event
	 * @param invokeIt
	 */
	public void broadcast(final Delegate<ListenerType> invokeIt) {
		for (final ListenerType l : listeners) 
			invokeIt.invoke(l);
	}
	public void broadcast(final String methodName, final Object... params) {
		if (listeners.size()<=0) return;
		else {
			final ListenerType listenerType = listeners.get(0);
			final Class<? extends Object> listenerTypeClass = listenerType.getClass();
			final Method declaredMethod = ReflectionUtils.getMethod(listenerTypeClass,methodName);
			if (declaredMethod==null) 
				throw new IllegalArgumentException("method doesnt exists!");
			for (final ListenerType l : listeners)
				try {
					declaredMethod.setAccessible(true);
					declaredMethod.invoke(l, params);
				} catch (final Exception e) {
					throw new IllegalArgumentException("couldnt invoke method!",e);
				}
		}

	}
}
